package com.pan.common.interview.jvm;

/**
 * 内存模型
 * @author by panstark
 * @description
 * @notice
 * @date 2020/12/25
 */
public class MemoryInfo {

    /************从线程角度来看*************/
    /**
     * java8 内存模型
     * 线程私有的：程序计数器（字节码指令no OOM）、虚拟机栈(java方法SOF&OOM)、本地方法栈(native方法 SOF&OOM)
     * 所有线程共有的：MetaSpace（类加载信息OOM）、java堆（常量池（字面量和符号引用量OOM）、数组和类对象）
     */

    /**
     * 程序计数器：（program counter register）
     * 当前线程所执行的字节码行号指示器（逻辑）
     * 改变计数器的值来选取下一条需要执行的字节码指令
     * 和线程是一对一关系即线程私有
     * 对java方法计数，对native方法则计数器为undefined
     * 不会发生内存泄漏
     */

    /**
     * java虚拟机栈：
     * java方法执行的内存模型
     * 包含多个栈帧
     *
     * 局部变量表：包含方法执行过程中的所有变量
     * 操作数栈：入栈、出栈、复制、交换、产生消费变量
     *
     * 递归为什么会出现栈溢出？
     * 虚拟机栈的深度是一定的，递归过深，栈帧会超出虚拟机栈深度
     * 也有可能引发outOfMemeoryException
     *
     */

    /**
     * 本地方法栈
     * 与虚拟机栈相似，主要作用标注了native的方法
     */

    /**
     * 元空间（MetaSpace）与永久代（PermGen）的区别
     * class类信息放在堆中，元空间在java7及以前是属于永久代的，在java8中分离出来了
     * 元空间使用是的本地内存（好处，老版本中的Java.lang.OutOfMemeryError:PermGen space 错误将不复存在），永久代使用的是jvm内存。
     * MetaSpace相比PermGem的优点：
     *   1、字符串常量池存在永久代中，容易出现性能问题和内存溢出
     *   2、类和方法的信息大小难确定，给永久代的大小指定带来困难
     *   3、永久代会给GC带来不必要的麻烦
     *   4、方便HOTSPOT与其他JVM如Jrockit的集成
     */

    /**
     * java堆（heap）线程共享
     * （新生代：（eden、survivor from，surivor to） 老年代）
     * 1、存储对象实例
     * 2、GC管理的主要区域
     */

    /************end*************/

    /**
     * java内存策略中堆和栈的区别--内存分配策略
     * 静态存储：编译时确定每个数据目标在运行时的存储空间需求
     * 栈式存储：数据区需求在编译时未知，运行模块入口前确定
     * 堆式存储：编译时或运行时模块入口否无法确定，动态分配
     *
     * 堆和栈的联系：
     * 引用对象、数组时，栈定义变量保存堆中目标的首地址
     * 堆和栈的区别：
     * 管理方式：栈自动释放、堆需要GC
     * 空间大些：栈比堆小
     * 碎片相关：栈产生的内存碎片比堆小
     * 分配方式：栈支持静态和动态分配，堆只支持动态分配
     * 效率：栈的效率比堆高
     */


}
